/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game;

import com.serponix.gui.WindowInterface;
import com.serponix.game.score.Score;
import com.serponix.game.food.Cherry;
import com.serponix.game.food.Cake;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.util.Collections;
import javax.swing.JLabel;
import com.serponix.net.Informace;

/**
 * Dědí z Modelu, reprezentuje mód classic.
 * @author Daniel Vala
 */
public class ModelClassic extends GameModel {

    private int vyskytBonusu = 3;
    private final int pocetBoduKJedneVyhre = 500;

    @SuppressWarnings("LeakingThisInConstructor")
    public ModelClassic(WindowInterface okno, GameParameters parametryHry, GamingArea herniPanel, JLabel[] skoreStitky, MessagePanel panelZprav) {
        super(okno, parametryHry, herniPanel, skoreStitky, panelZprav, parametryHry.getSizeOfGamingArea());
        parametryHry.getServer().setModel(this);
        net = parametryHry.getServer();
        hadi = new Snake[getPocetHadu()];
        vytvorListPocatecnichPozic(10);
        Collections.shuffle(listPocatecnichPozic);
        for (int i = 0; i < hadi.length; i++) {
            hadi[i] = new Snake(this, getHrac(i), listPocatecnichPozic.get(i), -1, Direction.DOWN,
                    3, getVelikostPolicka(), 10, 0, barvy[i], null, false, false);
            getHrac(i).init(this, hadi[i]);
        }
        jidlo = new Cake(this);

        startHry();
    }

    @Override
    public void jidloSezrano(Snake had) {
        had.prodluzHada();
        addScore(had.score, 50);
        jidlo.generateFood();
        int stesti = 1 + generatorNahody.nextInt(vyskytBonusu);
        if (stesti == 1 && bonus == null) {
            bonus = new Cherry(this);
        }
    }

    @Override
    public void bonusSezran(Snake had) {
        had.prodluzHada(6);
        addScore(had.score, 100);
        Toolkit.getDefaultToolkit().beep();
        bonus = null;
    }

    @Override
    public void resetHada(Snake had) {
        addScore(had.score, -10);
        Collections.shuffle(listPocatecnichPozic);
        had.setHad(listPocatecnichPozic.get(0), -1, Direction.DOWN);
    }

    @Override
    public void newRound() {
        Collections.shuffle(listPocatecnichPozic);
        Snake[] listHadu = getHadi();
        for (int i = 0; i < getPocetHadu(); i++) {
            listHadu[i].setHad(listPocatecnichPozic.get(i), -1, Direction.DOWN);
        }
        pockej(1000);
        jidlo.generateFood();
        bonus = null;
        ozivVsechnyHady();
    }

    @Override
    public void addScore(Score skore, int body) {
        skore.addSkore(body, pocetBoduKJedneVyhre);
    }

    // metoda krok kontroluje jestli had nenarazil do steny, jestli had neji a jestli had nenarazil do druheho hada
    @Override
    public void krok() {
        for (int i = 0; i < getPocetHadu(); i++) {
            getHrac(i).posunSe();
            setSkoreText(i, "Hrac " + getHrac(i).getJmeno() + ":   Skore: " + hadi[i].score.getSkore() + "   Vyhry: " + hadi[i].score.getPocetVyher() + "  |");
        }

        posliPole();
        posliStavStitku();
        posliInfo();
        posliKrok();

        setChanged();
        notifyObservers();
    }

    public void posliPole() {
        String zpravaKOdeslani = Informace.POLICKO + Informace.ODDELOVAC1;
        // přidání všech políček do zprávy
        if (jidlo != null) {
            zpravaKOdeslani += jidlo.getInstrukceProKresleni();
        }
        if (bonus != null) {
            zpravaKOdeslani += bonus.getInstrukceProKresleni();
        }
        for (int j = 0; j < getPocetHadu(); j++) {
            zpravaKOdeslani += hadi[j].getInstrukceProKresleni(false);
        }

        net.poslatData(zpravaKOdeslani);
    }

    public void posliKrok() {
        String zpravaKOdeslani = Informace.KROK + Informace.ODDELOVAC1;
        net.poslatData(zpravaKOdeslani);
    }

    public void posliStavStitku() {
        String zpravaKOdeslani = Informace.SKORE + Informace.ODDELOVAC1;

        // přidání textů všech štítků do zprávy
        for (int i = 0; i < getPocetHadu(); i++) {
            zpravaKOdeslani += getSkoreText(i) + Informace.ODDELOVAC3;
        }
        net.poslatData(zpravaKOdeslani);
    }

    public void posliInfo() {
        String zpravaKOdeslani = getPanelZprav().getMessageToSend();
        if (zpravaKOdeslani != null) {
            net.poslatData(zpravaKOdeslani);
        }
    }

    @Override
    public void paint(Graphics g) {
        if (!zobrazVeciNaPlose) {

            for (Snake had : hadi) {
                had.draw(g);
            }
            jidlo.draw(g);
            if (bonus != null) {
                bonus.draw(g);
            }
        } else {
            zobrazVeciNaPlose(g);
        }
    }

    @Override
    public void paintZdi(Graphics g) {
        getMapa().kresliMapu(g);
    }
}
